package org.ymh.unix_file_system.dao;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.ymh.unix_file_system.domain.FileSystemError;
import org.ymh.unix_file_system.domain.INode;
import org.ymh.unix_file_system.domain.GlobalVariable;

import java.util.HashMap;
import java.util.LinkedList;

/**
 * @author lenovo
 * @version 1.0
 * @description: TODO
 * @date 2023/12/15 17:20
 */
@Component
public class InodeOperate {
    @Autowired
    public GlobalVariable globalVariable;
    @Autowired
    public IndexOperate indexOperate;
    @Autowired
    public FileSystemError error;
    @Autowired
    public FreeBlockLinkedListOperate freeBlockLinkedListOperate;
    @Autowired
    public BlockOperate blockOperate;
    @Autowired
    public  FileSystemError fileSystemError;
    /**
    * @Description 获得一个空闲节点
    * @Author  lenovo
    * @Date   2023/12/17 19:06
    * @Param
    * @Return
    * @Exception
    */

    public int getFreeNodeNumber()
    {
        for (int i = 0; i < globalVariable.inodeBitMap.length; i++) {
            if(!globalVariable.inodeBitMap[i])
                return i;
        }
        fileSystemError.setError(fileSystemError.HaveNoRestInodeError);//没有多余节点
        return -1;
    }
    /**
    * @Description 分配特定节点
    * @Author  lenovo
    * @Date   2023/12/15 17:21
    * @Param
    * @Return
    * @Exception
    */
    public boolean inodeAllocation(int inodeNumber, INode inode)
    {
        if(!error.isOutIndex(inodeNumber, globalVariable.inodeArray.length,error.INodeIndexOutOfBoundsError)){

        if(globalVariable.inodeArray[inodeNumber]==null)
        {
            globalVariable.inodeArray[inodeNumber]=inode;
            globalVariable.inodeBitMap[inodeNumber]=true;
            return true;
        }}
        return false;
    }
    /**
    * @Description 删除一个i节点(判断该节点的连接个数）还要将所有的还给blocks和成组链接
    * @Author  lenovo
    * @Date   2023/12/15 17:24
    * @Param
    * @Return
    * @Exception
    */
    public boolean inodeDelete(int inodeNUmber)
    {
        if(!error.isOutIndex(inodeNUmber, globalVariable.inodeArray.length,error.INodeIndexOutOfBoundsError)){

                INode inode = globalVariable.inodeArray[inodeNUmber];
                if (inode != null) {
                    inode.setCount((byte) (inode.getCount() - 1));
                    if (inode.getCount() <= 0) {
                        HashMap<String, LinkedList<Integer>> occupyBlockByInode = indexOperate.getOccupyBlockByInode(inode);
                        LinkedList<Integer> data = occupyBlockByInode.get("data");
                        LinkedList<Integer> index = occupyBlockByInode.get("index");
                        if(data!=null)
                        {
                            for(Integer data1 : data)
                            {
                                blockOperate.blockRecycle(data1);
                                freeBlockLinkedListOperate.addFreeBlock(new short[]{(short)(int)data1});
                            }
                        }
                        if(index!=null)
                        {
                            for(Integer index1 : index)
                            {
                                blockOperate.blockRecycle(index1);
                                freeBlockLinkedListOperate.addFreeBlock(new short[]{(short)(int)index1});
                            }
                        }
                        globalVariable.inodeArray[inodeNUmber] = null;
                        globalVariable.inodeBitMap[inodeNUmber]=false;
                        
                    }
                    return true;
                }
            }
        return false;
    }


}
